<script lang="tsx" setup>
import { reactive, ref, toRefs, watch } from 'vue';
import type { FormRules } from 'naive-ui';
import { useNaiveForm } from '@/hooks/common/form';
import type { DeptTreeOption, RoleVO } from '@/service/types/system';
import { editDataScope, getRole, roleDeptTree } from '@/service/api/system/role';
import { useDict } from '@/utils/dict';
type Model = Pick<RoleVO, 'deptCheckStrictly' | 'deptIds' | 'roleId' | 'dataScope'>;
interface Props {
  currentDataScopeId: string | number | null | unknown;
}
const { sys_data_scope } = toRefs<any>(useDict('sys_data_scope'));

const loading = ref(false);
interface Emits {
  (e: 'submitted'): void;
}
const show = ref<boolean>(false);
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
defineOptions({
  name: 'ClientForm'
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const rules: FormRules = {
  dataScope: {
    required: true,
    message: '权限范围不能为空',
    trigger: 'blur'
  }
};

const visible = defineModel<boolean>('visible', {
  default: false
});
const currentModelData = ref<RoleVO>();
const model: Model = reactive(createDefaultModel());
const selectAllRef = ref<boolean>(false);
const selectChecKeys = ref<number[]>([]);
const depts = ref<DeptTreeOption[]>([]);
const cacheDepts = ref<DeptTreeOption[]>([]);
const allDeptIds = ref<number[]>([]);
const treeLoading = ref<boolean>(false);

const getAllIds = (data: DeptTreeOption[]): number[] => {
  const ids: number[] = [];
  const traverse = (obj: DeptTreeOption): void => {
    ids.push(obj.id as number);
    if (obj.children) {
      // 确保 children 存在
      obj.children.forEach(child => traverse(child));
    }
  };
  data.forEach(item => traverse(item));
  return ids;
};
function createDefaultModel(): Model {
  return {
    roleId: '',
    dataScope: null,
    deptCheckStrictly: false,
    deptIds: []
  };
}
const getRoleById = async (id: number) => {
  show.value = true;
  const { error, data } = await getRole(id);
  if (!error) {
    // @ts-expect-error 忽略Request请求
    currentModelData.value = data?.data;
  }
  show.value = false;
};
const getRoleDeptTree = async () => {
  if (cacheDepts.value.length <= 0) {
    treeLoading.value = true;
    const { error, data } = await roleDeptTree(props.currentDataScopeId as number);
    treeLoading.value = false;
    if (!error) {
      const deptData = data?.data?.depts;
      const ids = getAllIds(deptData as DeptTreeOption[]);
      allDeptIds.value = ids;
      depts.value = deptData;
      selectChecKeys.value = data?.data?.checkedKeys;
      cacheDepts.value = deptData;
    }
  } else {
    depts.value = cacheDepts.value;
    const ids = getAllIds(cacheDepts.value as DeptTreeOption[]);
    allDeptIds.value = ids;
  }
};
async function handleInitModel() {
  Object.assign(model, createDefaultModel());
  if (props.currentDataScopeId) {
    await getRoleById(props.currentDataScopeId as number);
    Object.assign(model, currentModelData.value);
  }
}

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    restoreValidation();
  }
});

const closeModal = () => {
  visible.value = false;
};
const submitDataScope = async (params: RoleVO) => {
  const { error, data } = await editDataScope(params);
  loading.value = false;
  if (!error) {
    (window as any).$message?.success(data?.msg);
    closeModal();
    emit('submitted');
  }
};
async function handleSubmit() {
  await validate();
  loading.value = true;
  const { ...params } = model;
  if (params.dataScope === '2') {
    params.deptIds = selectChecKeys.value as number[];
  }
  await submitDataScope({ ...params, roleId: props.currentDataScopeId } as RoleVO);
}
const handleSelectKey = (keys: any) => {
  selectChecKeys.value = keys;
};
// 全选
const selectAll = () => {
  if (selectAllRef.value) {
    selectChecKeys.value = [];
    selectAllRef.value = false;
  } else {
    selectChecKeys.value = allDeptIds.value;
    selectAllRef.value = true;
  }
};
const spanLeft = ref('24 s:24 m:24');
const spanRight = ref('24 s:24 m:12');
const widthClass = ref('w-400px');
watch(
  () => model.dataScope,
  () => {
    if (model.dataScope === '2') {
      getRoleDeptTree();
      spanLeft.value = '24 s:24 m:12';
      spanRight.value = '24 s:24 m:12';
      widthClass.value = 'w-740px';
    } else {
      depts.value = [];
      spanLeft.value = '24 s:24 m:24';
      widthClass.value = 'w-400px';
    }
  }
);
</script>

<template>
  <NModal v-model:show="visible" title="修改数据权限" preset="card" :class="widthClass">
    <NSpin :show="show">
      <NForm ref="formRef" :model="model" :rules="rules">
        <NGrid x-gap="12" responsive="screen" item-responsive>
          <NGi :span="spanLeft">
            <NFormItemGi span="24 s:24 m:24" path="dataScope" label="权限范围">
              <NSelect
                v-model:value="model.dataScope"
                filterable
                placeholder="请选择权限范围"
                :options="sys_data_scope"
              />
            </NFormItemGi>
          </NGi>
          <NGi v-if="model.dataScope == '2'" :span="spanRight" class="flex flex-col flex-gap-5px">
            <div class="flex justify-between">
              <div>数据权限</div>
              <div class="flex flex-gap-5px">
                <NButton size="tiny">展开/折叠</NButton>
                <NButton size="tiny" @click="selectAll">全选</NButton>
              </div>
            </div>
            <div class="flex items-center justify-between pl-8px pr-5px">
              <div class="flex items-center flex-gap-8px">
                <SvgIcon class="font-size-12px" icon="nimbus:arrows-horizontal" />
                <div>父子联动</div>
              </div>
              <NCheckbox v-model:checked="model.deptCheckStrictly" />
            </div>
            <div>
              <NSpin :show="treeLoading">
                <NScrollbar class="h-300px">
                  <NTree
                    block-line
                    :cascade="model.deptCheckStrictly"
                    checkable
                    :selectable="false"
                    checkbox-placement="right"
                    block-node
                    children-field="children"
                    key-field="id"
                    :data="depts"
                    :checked-keys="selectChecKeys"
                    @update:checked-keys="handleSelectKey"
                  >
                    <template #empty>
                      <Empty />
                    </template>
                  </NTree>
                </NScrollbar>
              </NSpin>
            </div>
          </NGi>
        </NGrid>
      </NForm>
    </NSpin>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="closeModal">取消</NButton>
        <NButton type="primary" :loading="loading" @click="handleSubmit">提交</NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style lang="scss" scoped></style>
